package se.slackers.sounder.algorithm;

public class FloatGameOfLifeRule extends AbstractRule {
	private static final float DECREMENT = 1f;
	private static final float APPROX_LIVE = 0.8f;

	private float decrement;
	private float surviveMin = 2f;
	private float surviveMax = 4f;

	private float birthMin = 3f;
	private float birthMax = 4f;

	public FloatGameOfLifeRule() {
		decrement = DECREMENT;
	}

	@Override
	void step(final float[] source, final float[] dest, final int w, final int h) {
		int index = 0;
		for (int y = 0; y < h; y++) {
			for (int x = 0; x < w; x++) {
				float neighbours = 0;
				for (int dy = -1; dy <= 1; dy++) {
					for (int dx = -1; dx <= 1; dx++) {
						if (dx != 0 || dy != 0) {
							neighbours += get(source, x + dx, y + dy);
						}
					}
				}

				if (get(source, x, y) >= APPROX_LIVE) {
					if (surviveMin <= neighbours && neighbours < surviveMax) {
						dest[index] = LIVE;
					} else {
						dest[index] = Math.max(0, dest[index] - decrement);
					}
				} else {
					if (birthMin <= neighbours && neighbours < birthMax) {
						dest[index] = LIVE;
					} else {
						dest[index] = Math.max(0, dest[index] - decrement);
					}
				}
				index++;
			}
		}
	}

	@Override
	public void param(final int n, final float value) {
		switch (n) {
		case 0:
			decrement = value;
			break;
		case 1:
			surviveMin = value;
			break;
		case 2:
			surviveMax = value;
			break;
		case 3:
			birthMin = value;
			break;
		case 4:
			birthMax = value;
			break;

		}
	}
}
